package com.espressif.iot.base.application;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import cn.sharesdk.framework.ShareSDK;

import com.espressif.iot.base.net.wifi.WifiAdmin;
import com.espressif.iot.base.threadpool.CachedThreadPool;
import com.espressif.iot.base.time.EspTimeManager;
import com.espressif.iot.db.IOTApDBManager;
import com.espressif.iot.db.IOTDeviceDBManager;
import com.espressif.iot.db.IOTDownloadIdValueDBManager;
import com.espressif.iot.db.IOTGenericDataDBManager;
import com.espressif.iot.db.IOTGenericDataDirectoryDBManager;
import com.espressif.iot.db.IOTUserDBManager;
import com.espressif.iot.db.IOTXqzoneDBManager;
import com.espressif.iot.db.greenrobot.daos.DaoMaster;
import com.espressif.iot.db.greenrobot.daos.DaoMaster.DevOpenHelper;
import com.espressif.iot.db.greenrobot.daos.DaoSession;
import com.espressif.iot.db.greenrobot.daos.DeviceDB;
import com.espressif.iot.db.greenrobot.daos.XqzoneDB;
import com.espressif.iot.log.InitLogger;
import com.espressif.iot.model.device.EspDeviceGateway;
import com.espressif.iot.ui.help.HelpEspUIActivity;
import com.espressif.iot.ui.main.EspUIActivity;
import com.espressif.iot.util.EspStrings;

import android.app.Application;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources;
import android.database.sqlite.SQLiteDatabase;
import android.net.DhcpInfo;
import android.net.wifi.WifiManager;
import android.os.Environment;

public class EspApplication extends Application
{
    private static EspApplication instance;
    private static Set<EspDeviceGateway> globalGWlist= new HashSet<EspDeviceGateway>();
	public static XqzoneDB  curzone=null;
    public static EspApplication sharedInstance()
    {
        if (instance == null)
        {
            throw new NullPointerException(
                "EspApplication instance is null, please register in AndroidManifest.xml first");
        }
        return instance;
    }
    public static  Set<EspDeviceGateway> GetGlobalGW(){
    	return  globalGWlist;
    }
    public static void   SetGlobalGW(EspDeviceGateway gate){
    	 globalGWlist.add(gate);
    }
    public static boolean GOOGLE_PALY_VERSION = false;
    
    @Override
    public void onCreate()
    {
        super.onCreate();
        instance = this;
        //初始化异步事件
        initAsyn();
        initSyn();
        
        initSpeech();
    }
    
    private void initSpeech() {
		// TODO Auto-generated method stub
    	// 应用程序入口处调用，避免手机内存过小，杀死后台进程后通过历史intent进入Activity造成SpeechUtility对象为null
    			// 如在Application中调用初始化，需要在Mainifest中注册该Applicaiton
    			// 注意：此接口在非主进程调用会返回null对象，如需在非主进程使用语音功能，请增加参数：SpeechConstant.FORCE_LOGIN+"=true"
    			// 参数间使用半角“,”分隔。
    			// 设置你申请的应用appid,请勿在'='与appid之间添加空格及空转义符
    			
    			// 注意： appid 必须和下载的SDK保持一致，否则会出现10407错误
    			
    			//SpeechUtility.createUtility(SpeechApp.this, "appid=" + getString(R.string.app_id));
    				
    			// 以下语句用于设置日志开关（默认开启），设置成false时关闭语音云SDK日志打印
    			// Setting.showLogcat(false);
	}
	public Context getContext()
    {
        return getBaseContext();
    }
    
    public Resources getResources()
    {
        return getBaseContext().getResources();
    }
    
    public String getVersionName()
    {
        String version = "";
        try
        {
            PackageInfo pi = getPackageManager().getPackageInfo(getPackageName(), 0);
            version = pi.versionName;
        }
        catch (NameNotFoundException e)
        {
            e.printStackTrace();
            version = "Not found version";
        }
        return version;
    }
    
    public int getVersionCode()
    {
        int code = 0;
        try
        {
            PackageInfo pi = getPackageManager().getPackageInfo(getPackageName(), 0);
            code = pi.versionCode;
        }
        catch (NameNotFoundException e)
        {
            e.printStackTrace();
        }
        return code;
    }
    
    public String getEspRootSDPath()
    {
        String path = null;
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
        {
            path = Environment.getExternalStorageDirectory().toString() + "/Espressif/";
        }
        return path;
    }
    
    public String getContextFilesDirPath()
    {
        return getFilesDir().toString();
    }
    
    private String __formatString(int value)
    {
        String strValue = "";
        byte[] ary = __intToByteArray(value);
        for (int i = ary.length - 1; i >= 0; i--)
        {
            strValue += (ary[i] & 0xFF);
            if (i > 0)
            {
                strValue += ".";
            }
        }
        return strValue;
    }
    
    private byte[] __intToByteArray(int value)
    {
        byte[] b = new byte[4];
        for (int i = 0; i < 4; i++)
        {
            int offset = (b.length - 1 - i) * 8;
            b[i] = (byte)((value >>> offset) & 0xFF);
        }
        return b;
    }
    
    public String getGateway()
    {
        WifiManager wm = (WifiManager)getSystemService(Context.WIFI_SERVICE);
        /* Return the DHCP-assigned addresses from the last successful 
         * DHCP request, if any.
         * dhcpInfo获取的是最后一次成功的相关信息，包括网关、ip等  
         * 返回的是路由器名称 gateway  地址  一般是192,.168.x.1
         * */
        DhcpInfo d = wm.getDhcpInfo();
        return __formatString(d.gateway);
    }
    
    private void initSyn()
    {
        // init db
        DevOpenHelper helper = new DaoMaster.DevOpenHelper(this, EspStrings.DB.DB_NAME, null);
        SQLiteDatabase db = helper.getWritableDatabase();
        DaoMaster daoMaster = new DaoMaster(db);
        DaoSession daoSession = daoMaster.newSession();
        IOTUserDBManager.init(daoSession);
        IOTDeviceDBManager.init(daoSession);
        IOTApDBManager.init(daoSession);
        IOTDownloadIdValueDBManager.init(daoSession);
        // zone init
        IOTXqzoneDBManager.init(daoSession);
        
        // data and data directory using seperate session for they maybe take long time
        daoSession = daoMaster.newSession();
        IOTGenericDataDBManager.init(daoSession);
        IOTGenericDataDirectoryDBManager.init(daoSession);
        
        // ShareSDK: third-party login
         
        List<DeviceDB> gwlist = IOTDeviceDBManager.getInstance().getGatewayDevices();
        if(gwlist.size()>0)
        for(DeviceDB gw: gwlist){
        	EspDeviceGateway gatew= new EspDeviceGateway(gw);
        	globalGWlist.add(gatew);
        }
        
        ShareSDK.initSDK(this);
    }
    
    private void initAsyn()
    {
        new Thread()
        {
            @Override
            public void run()
            {
                InitLogger.init();
                CachedThreadPool.getInstance();
                WifiAdmin.getInstance();
                EspTimeManager.getInstance().getUTCTimeLong();
            }
        }.start();
    }
    
    public final static boolean HELP_ON = true;
    
    public static Class<?> getEspUIActivity()
    {
        return HELP_ON ? HelpEspUIActivity.class : EspUIActivity.class;
    }
    
}
